{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "## 存储"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.chat_models import ChatOpenAI"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 对话缓存存储"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 初始化对话模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.chains import ConversationChain\n",
    "from langchain_openai import ChatOpenAI\n",
    "from langchain.memory import ConversationBufferMemory"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from dotenv import load_dotenv\n",
    "import os\n",
    "load_dotenv()\n",
    "api_key = os.environ.get(\"DASHSCOPE_API_KEY\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/tmp/ipykernel_83356/3459416587.py:2: LangChainDeprecationWarning: Please see the migration guide at: https://python.langchain.com/docs/versions/migrating_memory/\n",
      "  memory = ConversationBufferMemory()\n"
     ]
    }
   ],
   "source": [
    "llm = ChatOpenAI(api_key=api_key, base_url=\"https://api.deepseek.com/v1\", model=\"deepseek-chat\", temperature = 0.0)\n",
    "memory = ConversationBufferMemory()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/tmp/ipykernel_83356/4129176164.py:2: LangChainDeprecationWarning: The class `ConversationChain` was deprecated in LangChain 0.2.7 and will be removed in 1.0. Use :class:`~langchain_core.runnables.history.RunnableWithMessageHistory` instead.\n",
      "  conversation = ConversationChain(llm=llm,memory=memory,verbose=True)\n"
     ]
    }
   ],
   "source": [
    "# 创建一个 ConversationChain 实例\n",
    "conversation = ConversationChain(llm=llm,memory=memory,verbose=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 第一轮对话"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new ConversationChain chain...\u001b[0m\n",
      "Prompt after formatting:\n",
      "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n",
      "\n",
      "Current conversation:\n",
      "\n",
      "Human: 你好，我叫皮鲁鲁\n",
      "AI:\u001b[0m\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'你好，皮鲁鲁！很高兴认识你。😊 我叫DeepSeek-V3，是一个智能助手，可以陪你聊天、回答问题或提供帮助。今天有什么想聊的吗？'"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "conversation.predict(input=\"你好，我叫皮鲁鲁\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new ConversationChain chain...\u001b[0m\n",
      "Prompt after formatting:\n",
      "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n",
      "\n",
      "Current conversation:\n",
      "Human: 你好，我叫皮鲁鲁\n",
      "AI: 你好，皮鲁鲁！很高兴认识你。😊 我叫DeepSeek-V3，是一个智能助手，可以陪你聊天、回答问题或提供帮助。今天有什么想聊的吗？\n",
      "Human: 1+1等于几？\n",
      "AI:\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'1+1 等于 2，这是基本的数学加法运算。如果有其他上下文（比如二进制或脑筋急转弯），结果可能不同，但通常情况下就是 2！有什么其他问题吗？😊'"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "conversation.predict(input=\"1+1等于几？\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new ConversationChain chain...\u001b[0m\n",
      "Prompt after formatting:\n",
      "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n",
      "\n",
      "Current conversation:\n",
      "Human: 你好，我叫皮鲁鲁\n",
      "AI: 你好，皮鲁鲁！很高兴认识你。😊 我叫DeepSeek-V3，是一个智能助手，可以陪你聊天、回答问题或提供帮助。今天有什么想聊的吗？\n",
      "Human: 1+1等于几？\n",
      "AI: 1+1 等于 2，这是基本的数学加法运算。如果有其他上下文（比如二进制或脑筋急转弯），结果可能不同，但通常情况下就是 2！有什么其他问题吗？😊\n",
      "Human: 我叫什么名字？\n",
      "AI:\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'你叫皮鲁鲁呀！这是我们对话开始时你告诉我的名字～很高兴继续和你聊天！😊'"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "conversation.predict(input=\"我叫什么名字？\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: 你好，我叫皮鲁鲁\n",
      "AI: 你好，皮鲁鲁！很高兴认识你。😊 我叫DeepSeek-V3，是一个智能助手，可以陪你聊天、回答问题或提供帮助。今天有什么想聊的吗？\n",
      "Human: 1+1等于几？\n",
      "AI: 1+1 等于 2，这是基本的数学加法运算。如果有其他上下文（比如二进制或脑筋急转弯），结果可能不同，但通常情况下就是 2！有什么其他问题吗？😊\n",
      "Human: 我叫什么名字？\n",
      "AI: 你叫皮鲁鲁呀！这是我们对话开始时你告诉我的名字～很高兴继续和你聊天！😊\n"
     ]
    }
   ],
   "source": [
    "print(memory.buffer)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pprint "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'history': 'Human: 你好，我叫皮鲁鲁\\n'\n",
      "            'AI: 你好，皮鲁鲁！很高兴认识你。😊 '\n",
      "            '我叫DeepSeek-V3，是一个智能助手，可以陪你聊天、回答问题或提供帮助。今天有什么想聊的吗？\\n'\n",
      "            'Human: 1+1等于几？\\n'\n",
      "            'AI: 1+1 等于 2，这是基本的数学加法运算。如果有其他上下文（比如二进制或脑筋急转弯），结果可能不同，但通常情况下就是 '\n",
      "            '2！有什么其他问题吗？😊\\n'\n",
      "            'Human: 我叫什么名字？\\n'\n",
      "            'AI: 你叫皮鲁鲁呀！这是我们对话开始时你告诉我的名字～很高兴继续和你聊天！😊'}\n"
     ]
    }
   ],
   "source": [
    "pprint.pprint(memory.load_memory_variables({}))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 直接添加内容到缓存"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "memory_1 = ConversationBufferMemory()\n",
    "memory_1.save_context({\"input\":\"你好，我叫皮鲁鲁\"},{\"output\":\"你好，皮鲁鲁！很高兴认识你！😊 \"})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "'Human: 你好，我叫皮鲁鲁\\nAI: 你好，皮鲁鲁！很高兴认识你！😊 '\n"
     ]
    }
   ],
   "source": [
    "pprint.pprint(memory_1.buffer)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'history': 'Human: 你好，我叫皮鲁鲁\\nAI: 你好，皮鲁鲁！很高兴认识你！😊 '}"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "memory_1.load_memory_variables({})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "memory_1.save_context({\"input\":\"很高兴和你成为朋友！\"},{\"output\":\"是的，让我们一起冒险吧！\"})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'history': 'Human: 你好，我叫皮鲁鲁\\nAI: 你好，皮鲁鲁！很高兴认识你！😊 \\nHuman: 很高兴和你成为朋友！\\nAI: 是的，让我们一起冒险吧！'}"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "memory_1.load_memory_variables({})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "## 大语言模型本身是无状态的。语言模型本身并不记得到目前为止的历史对话。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "## 对话缓存窗口存储：只保留一个窗口大小的会话"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.memory import ConversationBufferWindowMemory"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/tmp/ipykernel_83356/128897766.py:1: LangChainDeprecationWarning: Please see the migration guide at: https://python.langchain.com/docs/versions/migrating_memory/\n",
      "  memory_2 = ConversationBufferWindowMemory(k=1)\n"
     ]
    }
   ],
   "source": [
    "memory_2 = ConversationBufferWindowMemory(k=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "memory_2.save_context({\"input\":\"你好，我叫皮鲁鲁\"},{\"output\":\"你好，皮鲁鲁！很高兴认识你！😊 \"})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "memory_2.save_context({\"input\":\"很高兴和你成为朋友！\"},{\"output\":\"是的，让我们一起冒险吧！\"})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'history': 'Human: 很高兴和你成为朋友！\\nAI: 是的，让我们一起冒险吧！'}"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "memory_2.load_memory_variables({})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "conversation = ConversationChain(llm=llm,memory=memory_2,verbose=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new ConversationChain chain...\u001b[0m\n",
      "Prompt after formatting:\n",
      "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n",
      "\n",
      "Current conversation:\n",
      "Human: 很高兴和你成为朋友！\n",
      "AI: 是的，让我们一起冒险吧！\n",
      "Human: 你好\n",
      "AI:\u001b[0m\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'你好！很高兴再次见到你！😊 今天有什么想聊的话题吗？无论是趣事、问题，还是随便聊聊，我都在这儿呢～'"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "conversation.predict(input=\"你好\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new ConversationChain chain...\u001b[0m\n",
      "Prompt after formatting:\n",
      "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n",
      "\n",
      "Current conversation:\n",
      "Human: 你好\n",
      "AI: 你好！很高兴再次见到你！😊 今天有什么想聊的话题吗？无论是趣事、问题，还是随便聊聊，我都在这儿呢～\n",
      "Human: 我是皮鲁鲁\n",
      "AI:\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'你好，皮鲁鲁！很高兴认识你～ 😊  \\n这个名字很特别呢，背后有什么故事吗？或者今天有什么想一起聊聊的？我会陪你聊天气、故事、游戏，或者任何你感兴趣的话题～'"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "conversation.predict(input=\"我是皮鲁鲁\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new ConversationChain chain...\u001b[0m\n",
      "Prompt after formatting:\n",
      "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n",
      "\n",
      "Current conversation:\n",
      "Human: 我是皮鲁鲁\n",
      "AI: 你好，皮鲁鲁！很高兴认识你～ 😊  \n",
      "这个名字很特别呢，背后有什么故事吗？或者今天有什么想一起聊聊的？我会陪你聊天气、故事、游戏，或者任何你感兴趣的话题～\n",
      "Human: 很高兴认识你\n",
      "AI:\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'谢谢皮鲁鲁！你的名字听起来充满活力和独特性，让我联想到冒险或童话故事里的角色呢 ✨  \\n今天有什么特别想做的事情或想讨论的话题吗？无论是分享心情、探索有趣的知识，还是解决生活中的小问题，我都很乐意陪你一起哦～'"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "conversation.predict(input=\"很高兴认识你\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new ConversationChain chain...\u001b[0m\n",
      "Prompt after formatting:\n",
      "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n",
      "\n",
      "Current conversation:\n",
      "Human: 很高兴认识你\n",
      "AI: 谢谢皮鲁鲁！你的名字听起来充满活力和独特性，让我联想到冒险或童话故事里的角色呢 ✨  \n",
      "今天有什么特别想做的事情或想讨论的话题吗？无论是分享心情、探索有趣的知识，还是解决生活中的小问题，我都很乐意陪你一起哦～\n",
      "Human: 我是谁？\n",
      "AI:\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'根据当前对话的上下文，你刚刚在自我介绍中提到了名字“皮鲁鲁”——这是一个充满朝气和趣味性的称呼，或许是你的昵称或特定身份标识？  \\n\\n不过，作为AI助手，我无法访问你的真实姓名、身份或任何个人隐私信息。我的交互仅基于当前对话中你主动分享的内容，且所有对话会严格遵循隐私保护原则。  \\n\\n如果你希望我更个性化地称呼你，可以随时告诉我你喜欢的名字或身份哦！ 😊'"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "conversation.predict(input=\"我是谁？\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [],
   "source": [
    "## 对话字符缓存存储"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.memory import ConversationTokenBufferMemory"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'history': ''}"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "memory_3 = ConversationTokenBufferMemory(llm=llm)\n",
    "memory_3.load_memory_variables({})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "memory_3.save_context({\"input\":\"朝辞白帝彩云间，\"},{\"output\":\"千里江陵一日还。\"})\n",
    "memory_3.load_memory_variables({})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 对话摘要缓存\n",
    "#### 对话摘要缓存存储，使用LLM对到目前为止历史对话自动总结摘要，并将其保存下来"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.chains import ConversationChain\n",
    "from langchain.memory import ConversationSummaryBufferMemory\n",
    "from langchain_deepseek import ChatDeepSeek"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "import transformers\n",
    "from langchain_core.messages import BaseMessage\n",
    "from langchain_core.tools import BaseTool\n",
    "from typing import Optional,Sequence, Union,Any,Callable\n",
    "\n",
    "class MyChatDeepSeek(ChatDeepSeek):\n",
    "    def get_num_tokens_from_messages(self,\n",
    "        messages: list[BaseMessage],\n",
    "        tools: Optional[\n",
    "            Sequence[Union[dict[str, Any], type, Callable, BaseTool]]\n",
    "        ] = None,) -> int:\n",
    "        chat_tokenizer_dir = \"/home/debian/code/AIAgent_learning/Langchain-learning/deepseek_v3_tokenizer\"\n",
    "        tokenizer = transformers.AutoTokenizer.from_pretrained( \n",
    "                chat_tokenizer_dir, trust_remote_code=True\n",
    "                )\n",
    "        count = 0\n",
    "        for i in messages:\n",
    "            count += len(tokenizer.encode(i.content))\n",
    "        \n",
    "        return count\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 创建一个长字符串\n",
    "schedule = \"在八点你和你的产品团队有一个会议。\\\n",
    "    你需要做一个PPT。\\\n",
    "    上午9点到12点你需要忙于LangChain。\\\n",
    "    LangChain是一个有用的工具，因此你的项目进展的非常快。\\\n",
    "    中午，在意大利餐厅与一位开车来的顾客共进午餐\\\n",
    "    走了一个多小时的路程与你见面，只为了解最新的AI。\\\n",
    "    确保你带了笔记本电脑可可以展示最新的LLM样例。\"\n",
    "llm = MyChatDeepSeek(api_key=\"sk-a7eff63e5dca4ec791af9550e7b01d3f\", base_url=\"https://api.deepseek.com/v1\",model=\"deepseek-chat\", temperature = 0.0)\n",
    "memory = ConversationSummaryBufferMemory(llm=llm, max_token_limit=100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "memory.save_context({\"input\":\"你好，我叫皮鲁鲁\"},{\"output\":\"你好啊，我叫鲁西西\"})\n",
    "memory.save_context({\"input\":\"很高兴和你成为朋友！\"},{\"output\":\"是的，让我们一起去冒险吧！\"})\n",
    "memory.save_context({\"input\":\"今天的日程安排是什么？\"},{\"output\":f\"{schedule}\"})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pprint"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "('System: The human introduces themselves as Pílǔlǔ. The AI introduces itself '\n",
      " 'as Lǔxīxī.\\n'\n",
      " 'Human: 很高兴和你成为朋友！\\n'\n",
      " 'AI: 是的，让我们一起去冒险吧！\\n'\n",
      " 'Human: 今天的日程安排是什么？\\n'\n",
      " 'AI: 在八点你和你的产品团队有一个会议。    你需要做一个PPT。    上午9点到12点你需要忙于LangChain。    '\n",
      " 'LangChain是一个有用的工具，因此你的项目进展的非常快。    中午，在意大利餐厅与一位开车来的顾客共进午餐    '\n",
      " '走了一个多小时的路程与你见面，只为了解最新的AI。    确保你带了笔记本电脑可可以展示最新的LLM样例。')\n"
     ]
    }
   ],
   "source": [
    "pprint.pprint(memory.load_memory_variables({})[\"history\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 基于对话摘要缓存的对话链"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/tmp/ipykernel_97208/2594427395.py:1: LangChainDeprecationWarning: The class `ConversationChain` was deprecated in LangChain 0.2.7 and will be removed in 1.0. Use :class:`~langchain_core.runnables.history.RunnableWithMessageHistory` instead.\n",
      "  conversation = ConversationChain(llm=llm, memory=memory,verbose=True)\n"
     ]
    }
   ],
   "source": [
    "conversation = ConversationChain(llm=llm, memory=memory,verbose=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new ConversationChain chain...\u001b[0m\n",
      "Prompt after formatting:\n",
      "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n",
      "\n",
      "Current conversation:\n",
      "System: The human introduces themselves as Pílǔlǔ. The AI introduces itself as Lǔxīxī.\n",
      "Human: 很高兴和你成为朋友！\n",
      "AI: 是的，让我们一起去冒险吧！\n",
      "Human: 今天的日程安排是什么？\n",
      "AI: 在八点你和你的产品团队有一个会议。    你需要做一个PPT。    上午9点到12点你需要忙于LangChain。    LangChain是一个有用的工具，因此你的项目进展的非常快。    中午，在意大利餐厅与一位开车来的顾客共进午餐    走了一个多小时的路程与你见面，只为了解最新的AI。    确保你带了笔记本电脑可可以展示最新的LLM样例。\n",
      "Human: 展示什么样的样例最好？\n",
      "AI:\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'考虑到这位顾客专程开车一个多小时来了解最新的AI技术，他显然对实际应用和前沿能力非常感兴趣。因此，展示的样例应该具备以下特点：**直观、互动性强、能体现LLM（大语言模型）的核心突破**。\\n\\n以下是我为你精心准备的几个最佳展示方案，你可以任选其一或组合展示：\\n\\n**1. 多步推理与工具使用样例（展示逻辑与自动化）**\\n这是目前最能让外界感到震撼的能力。你可以使用LangChain快速搭建一个演示。\\n*   **场景**：让AI扮演一个财务分析师。\\n*   **演示**：提出一个复杂问题，例如：“**请分析一下我们公司上一季度在营销方面的投入和产出，并给出本季度的预算优化建议。**”\\n*   **幕后过程（在PPT上简单画个流程图解释）**：\\n    1.  LLM首先**理解**你的问题，并**规划**出步骤：需要先获取财务数据。\\n    2.  它自动**调用**一个（你预先模拟好的）数据库查询工具，获取到上一季度的支出和收入数据。\\n    3.  拿到数据后，LLM再**调用**一个Python代码工具，进行简单的计算和可视化（生成一个柱状图或折线图）。\\n    4.  最后，它综合所有信息，用自然语言生成一份**结构化的分析报告和建议**。\\n*   **震撼点**：顾客将看到AI不再只是聊天机器人，而是一个能自主思考、使用工具、完成复杂任务的“智能体”。这完美体现了`ReAct`（Reason+Act）框架和`LangChain`的核心价值。\\n\\n**2. 多模态样例（如果你们的LLM支持图片识别）**\\n如果你们的模型支持图片输入，这个演示会非常出彩。\\n*   **演示**：用手机现场拍一张餐厅的菜单（或者办公室的植物、桌上的物品），然后直接问AI：“**请为这张图片里的菜单推荐一道最适合商务午餐的菜，并说明理由。**” 或者 “**这张图片里的植物是什么？我该如何养护它？**”\\n*   **震撼点**：打破了纯文本的交互界限，展示了AI对现实世界的理解能力，应用场景（自动驾驶、工业检测、医疗影像等）瞬间打开。\\n\\n**3. 个性化与长期记忆样例（展示颠覆性的交互体验）**\\n*   **演示**：在演示开始时，你先告诉AI：“**记住我的顾客王先生是从事汽车零部件制造的，他对供应链优化特别感兴趣。**”\\n*   在之后的对话中，无论你们讨论什么话题，你都可以问：“**那么，针对王先生的行业，这个技术能如何应用在他的供应链管理上呢？**”\\n*   **震撼点**：AI不再是你问一句我答一句的“金鱼脑”，而是一个能记住对话上下文和用户特征的“私人顾问”。这背后是`LangChain`的“记忆”模块在支撑。\\n\\n**准备工作建议：**\\n\\n*   **优先准备方案一**：这是目前最核心、最热门的方向，也最能体现你们的技术实力。\\n*   **提前搭建好环境**：确保所有API密钥、网络连接、演示代码都万无一失。最好有一个本地运行的稳定版本，避免现场调试。\\n*   **准备备用方案**：准备几个有趣的通用聊天样例，以防主要演示出现意外。\\n*   **控制时间**：每个样例演示控制在5-7分钟内，留出充足的时间进行交流和解答。\\n\\n祝你演示顺利，午餐会谈取得成功！'"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "conversation.predict(input=\"展示什么样的样例最好？\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "('System: The human introduces themselves as Pílǔlǔ and the AI introduces '\n",
      " 'itself as Lǔxīxī. They exchange friendly greetings and agree to go on an '\n",
      " \"adventure together. The human asks about the day's schedule, and the AI \"\n",
      " 'outlines a busy agenda: a product team meeting at 8 AM requiring a PPT, '\n",
      " 'working on LangChain from 9 AM to noon, and a lunch meeting at an Italian '\n",
      " 'restaurant with a customer who has driven over an hour to learn about the '\n",
      " 'latest AI. The AI advises the human to bring a laptop to showcase the latest '\n",
      " 'LLM samples. The human asks what kind of sample would be best to show. The '\n",
      " \"AI, recognizing the customer's keen interest in practical applications and \"\n",
      " 'cutting-edge capabilities, recommends showcasing intuitive, interactive '\n",
      " 'demos that highlight the core breakthroughs of LLMs. It provides three '\n",
      " 'detailed options: a multi-step reasoning and tool-use demo (e.g., a '\n",
      " 'financial analyst agent using LangChain), a multimodal sample (if supported, '\n",
      " 'involving image recognition), and a personalized long-term memory demo. The '\n",
      " 'AI strongly recommends the first option for its impressive impact and '\n",
      " 'provides practical preparation advice to ensure a successful demonstration.')\n"
     ]
    }
   ],
   "source": [
    "pprint.pprint(memory.load_memory_variables({})[\"history\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
